// -------------------------------------------------------------------------
// PARAMETERS:
// -------------------------------------------------------------------------


//transforms
float4x4 tW: WORLD; //the models world matrix
float4x4 tV: VIEW; //view matrix as set via Renderer (DX9)
float4x4 tP: PROJECTION; //projection matrix as set via Renderer (DX9)
float4x4 tWVP: WORLDVIEWPROJECTION;

//texture
texture Tex <string uiname="Texture";>;
sampler Samp = sampler_state //sampler for doing the texture-lookup
{
Texture = (Tex); //apply a texture to the sampler
MipFilter = LINEAR; //sampler states
MinFilter = LINEAR;
MagFilter = LINEAR;
};
//texture transformation marked with semantic TEXTUREMATRIX to achieve symmetric transformations
float4x4 tTex: TEXTUREMATRIX <string uiname="Texture Transform";>;

//offset factor
float factor <string uiname="offset";> = 1;
//texture size the render doesn't know it!
int TexWidth <string uiname="Texture Width";> = 256;
int TexHeight <string uiname="Texture Heihgt";> = 256;


//the data structure: "vertexshader to pixelshader"
//used as output data with the VS function
//and as input data with the PS function
struct vs2ps
{
float4 Pos : POSITION;
float4 TexCd : TEXCOORD0;

//define new var offset
float2 Offset : TEXCOORD1;

};

// -------------------------------------------------------------------------
// VERTEXSHADERS
// -------------------------------------------------------------------------
vs2ps VS(
float4 Pos : POSITION,
float4 TexCd : TEXCOORD0)
{
//inititalize all fields of output struct with 0
vs2ps Out = (vs2ps)0;

//transform position
Out.Pos = mul(Pos, tWVP);

//transform texturecoordinates
Out.TexCd = mul(TexCd, tTex);

//you can calculated things here aswell
//we calculated here the "pixelsize" = 1/texture size
//then the offset is pixelsize*factor
Out.Offset.x = 1*factor /float (TexWidth);
Out.Offset.y = 1*factor /float (TexHeight);


return Out;
}
// -------------------------------------------------------------------------
// PIXELSHADERS:
// -------------------------------------------------------------------------

// makes a very very simple blur
float4 PS3(vs2ps In): COLOR
{

//offset.x and offset.y comes from vertex function
//center
float4 center = tex2D(Samp, float2 (In.TexCd.x, In.TexCd.y));

//just the left half of the texture
if (In.TexCd.x < 1) {
//neighbours
//you can get "neighbour" pixels relativ to the position to center
float4 up = tex2D(Samp, float2 (In.TexCd.x, In.TexCd.y+In.Offset.y));
float4 up_left = tex2D(Samp, float2 (In.TexCd.x-In.Offset.x, In.TexCd.y+In.Offset.y));
float4 up_right = tex2D(Samp, float2 (In.TexCd.x+In.Offset.x, In.TexCd.y+In.Offset.y));
float4 down = tex2D(Samp, float2 (In.TexCd.x, In.TexCd.y-In.Offset.y));
float4 down_left = tex2D(Samp, float2 (In.TexCd.x-In.Offset.x, In.TexCd.y-In.Offset.y));
float4 down_right = tex2D(Samp, float2 (In.TexCd.x+In.Offset.x, In.TexCd.y-In.Offset.y));
float4 left = tex2D(Samp, float2 (In.TexCd.x-In.Offset.x, In.TexCd.y));
float4 right = tex2D(Samp, float2 (In.TexCd.x+In.Offset.x, In.TexCd.y));
//average of all neighbours
float4 average = (up + up_left + up_right + down + down_left + down_right + left + right)/8;
//set center color to average -> blur
center = average;
}
return center;
}

// bypass
float4 PS0(vs2ps In): COLOR
{
float4 col = tex2D(Samp, In.TexCd);
return col;
}

// -------------------------------------------------------------------------
// TECHNIQUES:
// -------------------------------------------------------------------------

technique Blur
{
pass P0
{
VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_2_0 PS3();
}
}

technique Bypass
{
pass P0
{
VertexShader = compile vs_1_1 VS();
PixelShader = compile ps_2_0 PS0();
}
}
